/*
 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
 * http://www.gnu.org/licenses/lgpl-3.0.html
 */

#ifndef SDK_GLOBALS_H
#define SDK_GLOBALS_H

#include <vector>

#include <wx/string.h>
#include <wx/treectrl.h>
#include <wx/file.h>
#include <wx/filename.h>
#include <wx/intl.h>
#include <wx/msgdlg.h>
#include <wx/bitmap.h>

#include "settings.h"

class TiXmlDocument;

/// Known plugin types
/// 已知插件类型
enum PluginType
{
    ptNone = 1,
    ptTool,
    ptMime,
    ptCompiler,
    ptDebugger,
    ptCodeCompletion,
    ptWizard,
    ptSmartIndent,
    ptOther
};

/// The type of module offering a context menu.
/// 提供上下文菜单的模块类型.
enum ModuleType
{
    mtProjectManager = 1,
    mtEditorManager,
    mtLogManager,
    mtOpenFilesList,
    mtEditorTab,
    mtUnknown
};

/// Known file types
/// 已知的文件类型
enum FileType
{
    ftCodeBlocksProject = 0,
    ftCodeBlocksWorkspace,
    ftDevCppProject,
    ftMSVC6Project,
    ftMSVC7Project,
    ftMSVC10Project,
    ftMSVC6Workspace,
    ftMSVC7Workspace,
    ftXcode1Project,
    ftXcode2Project,
    ftSource,
    ftHeader,
    ftTemplateSource,
    ftObject,
    ftXRCResource,
    ftResource,
    ftResourceBin,
    ftStaticLib,
    ftDynamicLib,
    ftExecutable,
    ftNative,
    ftXMLDocument,
    ftScript,
    ftOther
};

/**
* These are valid values for the state of each project file.
* If a value is casted to integer, it corresponds to the tree's imagelist index for the state.
* NOTE: Keep in sync with icons loaded in ProjectManager::BuildTree()!
*
* 这些是每个项目文件状态的有效值.
* 如果值被强制转换为整数,则它对应于状态树的imagelist索引.
* 注:与项目管理器构建树事件(ProjectManager::BuildTree())中加载的图标保持同步!
*
*/
enum FileVisualState
{
    // The following are related to (editable, source-) file states
    // 以下与(可编辑,源)文件状态相关
    fvsNormal = 0,
    fvsMissing,
    fvsModified,
    fvsReadOnly,
    // The following are related to version control systems (vc)
    // 以下与版本控制系统(vc)相关
    fvsVcAdded,
    fvsVcConflict,
    fvsVcMissing,
    fvsVcModified,
    fvsVcOutOfDate,
    fvsVcUpToDate,
    fvsVcRequiresLock,
    fvsVcExternal,
    fvsVcGotLock,
    fvsVcLockStolen,
    fvsVcMismatch,
    fvsVcNonControlled,
    // The following are related to C::B workspace/project/folder/virtual
    // 以下与C::B工作区项目虚拟目录(workspace/project/folder/virtual)相关
    fvsWorkspace,
    fvsWorkspaceReadOnly,
    fvsProject,
    fvsProjectReadOnly,
    fvsFolder,
    fvsVirtualFolder,

    /// do *not* use this, it exists just to know the number of items...
    /// 不要用这个,它的存在只是为了知道物品的数量...
    fvsLast
};

class DLLIMPORT cbProjectTreeImages
{
    public:
        static wxImageList* MakeImageList();

        /**
         * 返回值:The workspace icon index in the image list.
         * 参数:read_only Return the read-only icon for a workspace?
         *
         * 返回值:图像列表中的工作区图标索引.
         * 参数:只读返回工作区的只读图标?
         */
        static int WorkspaceIconIndex(bool read_only = false);
        /**
         * 返回值:  图像列表中的项目图标索引.
         * 参数:只读返回项目的只读图标?
         */
        static int ProjectIconIndex(bool read_only = false);
        /** 返回值:  图像列表中的文件夹图标索引. */
        static int FolderIconIndex();
        /** 返回值:  映像列表中的虚拟文件夹图标索引.*/
        static int VirtualFolderIconIndex();
};

/**
 * These are valid values for the visual style of the project tree.
 * They can be OR'ed to modify the representation of the project tree.
 * 这些是项目树视觉样式的有效值.它们可以修改项目树的表示形式.
*/
enum ProjectTreeVisualState
{
    //!< The default style: All "off"
    //!< 默认样式:全部"关闭"
    ptvsNone           = 0x00,
    //!< If true, use virtual folders like "Sources", "Headers", etc.
    //!< 如果为true,则使用"源文件","头文件"等虚拟文件夹.
    ptvsCategorize     = 0x01,
    //!< If true, create folders as needed. If false, the list is flat (not compatible with "hie folder name")
    //!< 如果为true,则根据需要创建文件夹.如果为false,则列表是平面的(与"hie文件夹名"不兼容)
    ptvsUseFolders     = 0x02,
    //!< If true, the folder name will be hidden and only the file name will be shown (not compatible with "use folders")
    //!< 如果为true,则文件夹名称将隐藏,仅显示文件名(与"使用文件夹"不兼容)
    ptvsHideFolderName = 0x04,
    //!< Just here for convenience, "categorise" + "use folders" ON
    //!< 为了方便起见,请在此处"分类(categorise)"+"使用文件夹"
    ptvsDefault        = 0x03
};

/**
 * Template output types.
 * 模板输出类型.
 * */
enum TemplateOutputType
{
    ///< template outputs a new project
    ///< 模板输出新项目
    totProject = 0,
    ///< template adds a new target in a project
    ///< 模板在项目中添加新目标
    totTarget,
    ///< template outputs a new file (or files)
    ///< 模板输出一个或多个新文件
    totFiles,
    ///< template produces custom output (entirely up to the wizard used)
    ///< 模板生成自定义输出(完全取决于使用的向导)
    totCustom,
    ///< template is a user-saved project template
    ///< 模板是用户保存的项目模板
    totUser
};

/**
 * Supported platforms
 * 支持的平台类型
 * */
enum SupportedPlatforms
{
    spMac       = 0x01,
    spUnix      = 0x02,
    spWindows   = 0x04,

    spAll       = 0xff
};
// NOTE: if you add/remove platforms, remember to update the relevant Get/Set globals
// 注:如果添加/删除平台,请记住更新相关的Get/Set全局函数

typedef wxString HighlightLanguage;
#define HL_AUTO _T(" ")
#define HL_NONE _T("  ")

extern DLLIMPORT const wxString DEFAULT_WORKSPACE;
extern DLLIMPORT const wxString DEFAULT_ARRAY_SEP;
extern DLLIMPORT const wxString DEFAULT_CONSOLE_TERM;
extern DLLIMPORT const wxString DEFAULT_CONSOLE_SHELL;
extern DLLIMPORT const wxString cbDEFAULT_OPEN_FOLDER_CMD;

// global helper funcs
/// Reads a wxString from a non-unicode file. File must be open. File is closed automatically.
/// 全局帮助函数
/// 从非unicode文件读取一个(wxString类型)字符串.文件必须打开.文件将自动关闭.
extern DLLIMPORT bool cbRead(wxFile& file, wxString& st, wxFontEncoding encoding = wxFONTENCODING_SYSTEM);
/// Reads a wxString from a non-unicode file. File must be open. File is closed automatically.
extern DLLIMPORT wxString cbReadFileContents(wxFile& file, wxFontEncoding encoding = wxFONTENCODING_SYSTEM);
/// Writes a wxString to a non-unicode file. File must be open. File is closed automatically.
extern DLLIMPORT bool cbWrite(wxFile& file, const wxString& buff, wxFontEncoding encoding = wxFONTENCODING_SYSTEM);
/// Writes a wxString to a file. Takes care of unicode and uses a temporary file to save first and then it copies it over the original.
/// 将一个(wxString)类型字符串写入文件.处理unicode并首先使用临时文件进行保存,然后将其复制到原始文件上.
extern DLLIMPORT bool cbSaveToFile(const wxString& filename, const wxString& contents, wxFontEncoding encoding = wxFONTENCODING_SYSTEM, bool bom = false);
/// Saves a TinyXML document correctly, even if the path contains unicode characters.
/// 正确保存TinyXML文档,即使路径包含unicode字符.
extern DLLIMPORT bool cbSaveTinyXMLDocument(TiXmlDocument* doc, const wxString& filename);
/// Return @c str as a proper unicode-compatible string
/// 返回(@c str)作为一个适当的unicode兼容字符串
extern DLLIMPORT wxString cbC2U(const char* str);
/// Return multibyte (C string) representation of the string
/// 返回字符串的多字节(C字符串)表示形式
extern DLLIMPORT const wxWX2MBbuf cbU2C(const wxString& str);
/// Try converting a C-string from different encodings until a possible match is found.
/// This tries the following encoding converters (in the same order):
/// utf8, system, default and iso8859-1 to iso8859-15.
/// Returns the final encoding detected.
///
/// 尝试从不同的编码转换C字符串,直到找到可能的匹配项.
/// 这将尝试以下编码转换器(按相同顺序): utf8, system, default and iso8859-1 to iso8859-15.
/// 返回检测到的最终编码.
extern DLLIMPORT wxFontEncoding DetectEncodingAndConvert(const char* strIn, wxString& strOut, wxFontEncoding possibleEncoding = wxFONTENCODING_SYSTEM);

/// Return an integer representation of a platform string
/// 返回平台字符串的整数表示形式
extern DLLIMPORT int GetPlatformsFromString(const wxString& platforms);
/// Return a string representation of a platform / multiple platforms
/// 返回一个平台/多个平台的字符串表示形式
extern DLLIMPORT wxString GetStringFromPlatforms(int platforms, bool forceSeparate = false);

// see globals.cpp for info on the third argument (bool SeparatorAtEnd)
// 有关第三个参数(bool SeparatorAtEnd)的信息,请参见globals.cpp
extern DLLIMPORT wxString GetStringFromArray(const wxArrayString& array, const wxString& separator = DEFAULT_ARRAY_SEP, bool SeparatorAtEnd = true);
extern DLLIMPORT wxArrayString GetArrayFromString(const wxString& text, const wxString& separator = DEFAULT_ARRAY_SEP, bool trimSpaces = true);
typedef std::vector<wxString> wxStringVec;
extern DLLIMPORT wxStringVec GetVectorFromString(const wxString& text,
                                                 const wxString& separator = DEFAULT_ARRAY_SEP,
                                                 bool trimSpaces = true);
extern DLLIMPORT wxArrayString MakeUniqueArray(const wxArrayString& array, bool caseSens);
extern DLLIMPORT wxString MakeUniqueString(const wxString& text,  const wxString& separator = DEFAULT_ARRAY_SEP, bool caseSens = true);
extern DLLIMPORT void AppendArray(const wxArrayString& from, wxArrayString& to);

extern DLLIMPORT wxString UnixFilename(const wxString& filename, wxPathFormat format = wxPATH_NATIVE);
extern DLLIMPORT void QuoteStringIfNeeded(wxString& str);
extern DLLIMPORT bool NeedQuotes(const wxString &str);

/// Escapes spaces and tabs (NOT quoting the string)
/// 转义空格和制表符(不引用字符串)
extern DLLIMPORT wxString EscapeSpaces(const wxString& str);

extern DLLIMPORT FileType FileTypeOf(const wxString& filename);
extern DLLIMPORT wxString cbFindFileInPATH(const wxString &filename);

extern DLLIMPORT void SaveTreeState(wxTreeCtrl* tree, const wxTreeItemId& parent, wxArrayString& nodePaths, wxArrayString& selectedItemPaths);
extern DLLIMPORT void RestoreTreeState(wxTreeCtrl* tree, const wxTreeItemId& parent, wxArrayString& nodePaths, wxArrayString& selectedItemPaths);

extern DLLIMPORT bool CreateDirRecursively(const wxString& full_path, int perms = 0755);
extern DLLIMPORT bool CreateDir(const wxString& full_path, int perms = 0755);
extern DLLIMPORT wxString ChooseDirectory(wxWindow* parent,
                                          const wxString& message = _("Select directory"),
                                          const wxString& initialPath = _T(""),
                                          const wxString& basePath = _T(""),
                                          bool askToMakeRelative = false, // relative to basePath
                                          bool showCreateDirButton = false); // where supported

extern DLLIMPORT bool NormalizePath(wxFileName& f,const wxString& base);
extern DLLIMPORT bool IsSuffixOfPath(wxFileName const & suffix, wxFileName const & path);

/// If path is pointing to a symlink then the function will set dirpath parameter to the path the symlink points to.
/// 如果路径指向符号链接,则函数将dirpath参数设置为符号链接指向的路径.
///
/// 注释: 在windows上什么也不做.
/// 注释: 应仅用于指向目录的路径.
/// 返回值: 正确解析符号链接时为true,否则为false.
extern DLLIMPORT bool cbResolveSymLinkedDirPath(wxString& dirpath);
/// 调用cbResolveSymLinkedPath,直到路径不是符号链接为止.
/// 注释: 在windows上什么也不做.
/// 注释: 应仅用于指向目录的路径.
/// 返回值: 解析路径,如果不是符号链接,则为同一路径.
extern DLLIMPORT wxString cbResolveSymLinkedDirPathRecursive(wxString dirpath);

/**
 * Reads settings if eolMode is -1
  * Expected input (defined in sdk/wxscintilla/include/wx/wxscintilla.h) is:
  * wxSCI_EOL_CRLF=0, wxSCI_EOL_CR=1, or wxSCI_EOL_LF=2
  *
  * 如果eolMode为-1,则读取设置
  * 预期输入(在sdk/wxscintilla/include/wx/wxscintilla.h中定义)是:
  */
extern DLLIMPORT wxString GetEOLStr(int eolMode = -1);

extern DLLIMPORT wxString URLEncode(const wxString &str);

extern DLLIMPORT wxString ExpandBackticks(wxString &str);

/**
 * This function creates a new wxMenu object on the heap and recursively
  * copies a given menu into it.
  *
  * It's up to the user to make sure the returned menu is deleted.
  *
  * 参数说明: mnu The menu to copy
  * 参数说明: with_accelerators If true, also copies the accelerators (defaults to false).
  * 返回值:  The copied menu or a nullptr, if the menu to copy was empty or NULL
  *
  * 此函数在堆上创建一个新的wxMenu对象,并递归地将给定的菜单复制到其中.
  * 由用户来确定返回的菜单是否被删除.
  * 参数说明: mnu 要复制的菜单
  * 参数说明: 如果为true,则还可以复制加速器(默认为false).
  * 返回值:  如果要复制的菜单为空或空,则为复制的菜单或空指针
  */
extern DLLIMPORT wxMenu* CopyMenu(wxMenu* mnu, bool with_accelerators = false);

/// Check if CommonControls version is at least 6 (XP and up)
/// 检查CommonControls版本是否至少为6(XP及以上)
extern DLLIMPORT bool UsesCommonControls6();

/**
 * This function loads a bitmap from disk.
  * Always use this to load bitmaps because it takes care of various
  * issues with pre-XP windows (actually common controls < 6.00).
  *
  * 此函数用于从磁盘加载位图.
  * 始终使用此选项加载位图,因为它解决了XP以前的窗口(实际上是常见控件<6.00)的各种问题.
  */
extern DLLIMPORT wxBitmap cbLoadBitmap(const wxString& filename, wxBitmapType bitmapType = wxBITMAP_TYPE_PNG);

// compatibility function
// 兼容函数
inline wxBitmap LoadPNGWindows2000Hack(const wxString& filename){ return cbLoadBitmap(filename); }

/**
 * Finds out if a window is really shown.
  *
  * win->IsShown() is not that good because we don't know if the
  * window's container (parent) is actually shown or not...
  *
  * This is usually used to find out if docked windows are shown.
  *
  * 参数说明: win 有问题的窗口.
  * 返回值: 如果显示@c win,则为True,否则为false.
  *
  * 找出是否确实显示了窗口.
  * win->IsShown()不是很好,因为我们不知道窗口的容器(父)是否实际显示...
  * 这通常用于确定是否显示停靠窗口.
  */
extern DLLIMPORT bool IsWindowReallyShown(wxWindow* win);

/**
 * Icons styles for settings dialogs.
 * 设置对话框的图标样式.
  */
enum SettingsIconsStyle
{
    ///< Large icons (default)
    ///< 大图标(默认值)
    sisLargeIcons    = 0,
    ///< No icons, just text
    ///< 没有图标,只有文本
    sisNoIcons       = 1
};

class wxListCtrl;

/**
 * Set the icons style for the supplied list control.
 * 为提供的列表控件设置图标样式.
  * 参数说明: lc 列表控件(wxListCtrl).
  * 参数说明: style 要使用的样式.
  */
extern DLLIMPORT void SetSettingsIconsStyle(wxListCtrl* lc, SettingsIconsStyle style);
/** Get the icons style set in environment-dialog.
 * 在"环境"对话框中获取图标样式集.
  * This version is left for backwardscompatibility.
  * 此版本保留为向后兼容(backwardscompatibility).
  * 返回值:  图标样式
  */
extern DLLIMPORT SettingsIconsStyle GetSettingsIconsStyle(wxListCtrl* lc);
/** Get the icons style set in environment-dialog.
 * 在"环境"对话框中获取图标样式集.
  * 返回值:  图标样式.
  */
extern DLLIMPORT SettingsIconsStyle GetSettingsIconsStyle();

class wxWindow;

enum cbPlaceDialogMode
{
    pdlDont = 0,
    pdlBest,
    pdlCentre,
    pdlHead,
    pdlConstrain,
    pdlClip
};

extern DLLIMPORT void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode = pdlBest, bool enforce = false);

/**
 * wxMessageBox wrapper.
 * 消息框包裹器
  *
  * Use this instead of wxMessageBox(), as this uses PlaceWindow() to show it in the correct monitor.
  * 使用它而不是wxMessageBox(),因为它使用PlaceWindow()在正确的监视器中显示它.
  * 注释: The return value for wxOK would be wxID_OK and so on for other buttons.
  * wxOK的返回值是wxID_OK,其他按钮的返回值是wxID_OK,依此类推.
  * So, read wxMessageDialog 's documentation, *not* wxMessageBox 's...
  * 所以,请阅读wxMessageDialog的文档,而不是wxMessageBox的...
  */
extern DLLIMPORT int cbMessageBox(const wxString& message, const wxString& caption = wxEmptyString, int style = wxOK, wxWindow *parent = NULL, int x = -1, int y = -1);

extern DLLIMPORT int cbGetSingleChoiceIndex(const wxString& message, const wxString& caption,
                                            const wxArrayString& choices, wxWindow *parent = NULL,
                                            const wxSize &size = wxSize(300, 300),
                                            int initialSelection = 0);

/** wxMultiChoiceDialog wrapper.
 * 多项选择包裹器
  *
  * Use this instead of wxMessageBox(), as this uses PlaceWindow() to show it in the correct monitor.
  * 使用它而不是wxMessageBox(),因为它使用PlaceWindow()在正确的监视器中显示它.
  */
extern DLLIMPORT wxArrayInt cbGetMultiChoiceDialog(const wxString& message, const wxString& caption,
                                     const wxArrayString& choices, wxWindow *parent = nullptr,
                                     const wxSize& size = wxSize(300, 300),
                                     const wxArrayInt& initialSelection = wxArrayInt());

#if wxCHECK_VERSION(3, 0, 0)
extern DLLIMPORT const char *cbGetTextFromUserPromptStr;
#else
extern DLLIMPORT const wxChar *cbGetTextFromUserPromptStr;
#endif // wxCHECK_VERSION

extern DLLIMPORT wxString cbGetTextFromUser(const wxString &message,
                                            const wxString &caption = cbGetTextFromUserPromptStr,
                                            const wxString &default_value = wxEmptyString, wxWindow *parent = NULL,
                                            int x = wxDefaultCoord, int y = wxDefaultCoord, bool centre = true);

inline void NotifyMissingFile(const wxString &name)
{
    wxString msg;
    msg.Printf(wxT("找不到文件%s.\n请检查您的安装."), name.wx_str());
    cbMessageBox(msg);
}

/// Result values of cbDirAccessCheck()
/// 目录访问检查(cbDirAccessCheck())的结果值
enum DirAccessCheck
{
    ///< Invalid directory (does not exist).
    ///< 无效目录(不存在).
    dacInvalidDir,
    ///< Current user has read-write access to the directory.
    ///< 当前用户对目录具有读写访问权限.
    dacReadWrite,
    ///< Current user has read-only access to the directory.
    ///< 当前用户对目录具有只读访问权限.
    dacReadOnly
};

/** Check what access the current user has in a directory.
  *检查当前用户在目录中的访问权限.
  * 参数说明: dir 有问题的目录,它可能包含也可能不包含结束路径分隔符.
  * 返回值:  当前用户在目录中的访问类型.
  */
extern DLLIMPORT DirAccessCheck cbDirAccessCheck(const wxString& dir);

namespace platform
{
    typedef enum
    {
        winver_NotWindows = 0,
        winver_UnknownWindows,
        winver_Windows9598ME,
        winver_WindowsNT2000,
        winver_WindowsXP,
        winver_WindowsServer2003,
        winver_WindowsVista,
        winver_Windows7
    }windows_version_t;

    extern DLLIMPORT windows_version_t WindowsVersion();
}

// returns the real path of a file by resolving symlinks
// not yet optimal but should do for now
// one thing that's not checked yet are circular symlinks - watch out!
//
// 通过解析尚未优化的符号链接返回文件的实际路径,但现在应该做的一件事是循环符号链接-小心!
//
extern DLLIMPORT wxString realpath(const wxString& path);

#endif // SDK_GLOBALS_H
